
require "base_def"
local redis = require "skynet.db.redis"

local redis_tools = {}

function redis_tools:Init()
    self.redis = nil
    --版本
    self.redisVersion = nil 
    --主版本       
    self.mainVersion = nil          

    local host = skynet.getenv('redis_server')
    self:Connect(host)
end

function redis_tools:Connect(host, port)
    local ok
    local conf = {
        host = host, port = port or 6379, db = 0
    }
    ok, self.redis = pcall(redis.connect, conf)
    
    if not ok then
        --log.info('redis.connect failed, err msg:', self.redis, 'config:', conf)
        self.redis = nil
        skynet.exit()
        return
    end

    local okk, info = pcall(self.redis.info, self.redis, 'Server')
    if okk then
        local s, e = string.find(info, 'redis_version:')
        if s and s > 0 then
            self.redisVersion = info.sub(info, e + 1, e + 6)
            self.mainVersion = tonumber(string.sub(self.redisVersion, 1, 1))
        end
    end

    if self.redisVersion then
        --log.info('redis host:', conf.host, 'version:', self.redisVersion)
        --log.info('redis_tools version:', self.redisVersion)
        --log.info("redis_tools self.redis=", self.redis)
    else
        --log.info('get redis info failed!!!')
    end
end

function redis_tools:Watch(host, port)
    local conf = {
        host = host, port = port or 6379, db = 0
    }
    local ok, ret = pcall(redis.watch, conf)
    if ok then
        return ret
    else
        --log.info('redis watch failed err msg:', ret, 'config:', conf)
    end
end


local function safe_hset_single(self, key, field1, val1)
    local ok, ret = pcall(self.redis.hset, self.redis, key, field1, val1)
    if not ok then
        --log.info('redis hset error', ret, key, field1, val1)
        return
    end
    return true
end

function redis_tools:SafeHset(key, field, val1, ...)
    --log.info("key=", key)
    --log.info("field=", field)
    --log.info("val1=", val1)
    if self.mainVersion and self.mainVersion >= 4 then
        local ok, ret = pcall(self.redis.hset, self.redis, key, field, val1, ...)
        if not ok then
            log.error("redis_tools:SafeHset error!")
            return
        end
    else
        if not safe_hset_single(self, key, field, val1) then
            return 
        end
        local left = table.pack(...)
        local len = #left
        if len > 0 then
            if len % 2 == 0 then
                local half = math.floor(len / 2)
                for i = 1, half do
                    if not safe_hset_single(self, key, left[i * 2 - 1], left[i * 2]) then
                        return
                    end
                end
            else
                --log.info('safe_hset param num is not even')
                return 
            end
        end
    end

    return true
end

function redis_tools:SafeHget(key, field)
    local ok, ret = pcall(self.redis.hget, self.redis, key, field)
    if not ok then
        --log.info('redis hget error', ret, key, field)
        return
    end

    return ok, ret
end


function redis_tools:SafeIncr(key, field)
    local ok, ret = pcall(self.redis.incr, self.redis, key, field)
    if not ok then
        log.info('redis incr error', ret)
        return
    end
    
    return ok, ret
end

skynet.start(function()
    skynet.dispatch("lua", function(session, address, cmd, ...)
        --log.info("redis_tools dispatch cmd=", cmd)
        local f = redis_tools[cmd]
        if f then
            skynet.ret(skynet.pack(f(redis_tools, ...)))
        else
            log.error(string.format("Unknown command %s", tostring(cmd)))
        end
    end)

    skynet.register(".redis_tools")
    redis_tools:Init()
end)

return redis_tools